package com.wen.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wen.common.dto.RoleDTO;
import com.wen.common.pojo.system.Permission;
import com.wen.common.pojo.system.Role;
import com.wen.common.pojo.system.RolePermission;
import com.wen.common.pojo.system.User;
import com.wen.common.pojo.system.oauth.OAuthUser;
import com.wen.common.utils.ResponseResult;
import com.wen.system.mapper.PermissionMapper;
import com.wen.system.mapper.RoleMapper;
import com.wen.system.mapper.UserMapper;
import com.wen.system.service.OAuthService;
import com.wen.system.service.PermissionService;
import com.wen.system.service.RoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
@Slf4j
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private RoleService roleService;

    @Override
    public Role findRoleById(Long roleId) {
        return roleMapper.findRoleById(roleId);
    }

    @Override
    public List<Role> findAll() {
        return roleMapper.selectList(null);
    }

    @Override
    public List<RoleDTO> findRole(int pageNum, int pageSize, String search) {
        LambdaQueryWrapper<Role> wrapper = Wrappers.lambdaQuery();
        if (StrUtil.isNotBlank(search)) {
            wrapper.like(Role::getName, search);
        }
        Page<Role> rolePage = roleMapper.selectPage(new Page<>(pageNum, pageSize), wrapper);
        // 给角色绑定权限数组id （项目demo上此处是要绑定的，后看）
        List<Role> records = rolePage.getRecords();
        ArrayList<RoleDTO> roleDTORecords = new ArrayList<>();
        for (Role role : records) {

            RoleDTO roleDto = new RoleDTO();
            ArrayList<Long> permissionList = new ArrayList<>();// 权限数组
            //将前面值的属性复制给后面dto
            BeanUtils.copyProperties(role, roleDto);
            // 查出当前角色拥有的权限id
            List<RolePermission> rolePermissions = roleMapper.getRolePermissionByRoleId(roleDto.getId());
            // 遍历权限id放入数组中
            for (RolePermission rolePermission : rolePermissions) {
                Long permissionId = rolePermission.getPermissionId();
                permissionList.add(permissionId);
            }
            roleDto.setPermissions(permissionList);
            // 将roleDto添加到Records数组里返回
            roleDTORecords.add(roleDto);
        }
        return roleDTORecords;
    }

    @Override
    public Page<RoleDTO> rolePage(int pageNum, int pageSize, String search) {
        LambdaQueryWrapper<Role> wrapper = Wrappers.lambdaQuery();
        if (StrUtil.isNotBlank(search)) {
            wrapper.like(Role::getName, search);
        }
        Page<Role> page = new Page<>(pageNum, pageSize);
        Page<Role> rolePage = roleMapper.selectPage(page, wrapper);
        /*
          封装rolePage
          思路：换掉rolePage里面的records数组
         */
        Page<RoleDTO> roleDtoPage = new Page<>(pageNum, pageSize);
        BeanUtils.copyProperties(rolePage, roleDtoPage);

        List<RoleDTO> records = findRole(pageNum, pageSize, search);

        return roleDtoPage.setRecords(records);
    }

    @Override
    public List<Permission> findPermissionByRoleId(Long roleId) {

        // 根据角色的id查出所有权限的id集合
        List<RolePermission> permissionList = roleMapper.getRolePermissionByRoleId(roleId);
        System.out.println("====================" + permissionList);
        ArrayList<Permission> list = new ArrayList<>();
        // 遍历这个权限集合，通过id去权限表查每条权限（菜单）
        for (RolePermission rolePermission : permissionList) {
            QueryWrapper<Permission> wrapper = new QueryWrapper<>();

            wrapper.eq("id", rolePermission.getPermissionId());
            Permission permission = permissionMapper.selectOne(wrapper);
            if (permission != null) {
                list.add(permission);
            }
        }
        return list;
    }


    @Override
    public int addRole(Role role) {
        return roleMapper.insert(role);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delRole(Long id) {
        // 删除角色下关联的permission，
        roleMapper.delRolePermissionsByRoleId(id);
        // 更新userRole
        userMapper.deleteUserRoleByRoleId(id);
        return roleMapper.deleteById(id);
    }

    @Override
    public int update(Role role) {
        return roleMapper.updateById(role);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<?> changePermission(RoleDTO roleDTO) {
        // 先根据角色id删除所有的角色跟权限的绑定关系
        roleMapper.delRolePermissionsByRoleId(roleDTO.getId());

        for (Long permissionId : roleDTO.getPermissions()) {
            roleMapper.insertRoleAndPermission(roleDTO.getId(), permissionId);
        }
        //返回当前用户角色的权限菜单，（返回菜单树）
        List<Permission> permissions = roleService.findPermissionByRoleId(roleDTO.getId()); //todo: 事务失效
        List<Permission> menuTree = permissionService.getMenuTree(permissions, 0);
        return ResponseResult.success(menuTree);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<?> delRoleBatch(List<Long> ids) {
        roleMapper.deleteBatchIds(ids);
        ids.forEach(id ->{
            // 删除角色下关联的permission，
            roleMapper.delRolePermissionsByRoleId(id);
            // 更新userRole
            userMapper.deleteUserRoleByRoleId(id);
        });
        return ResponseResult.success();
    }
}
